package com.ltedu.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ltedu.common.contants.Constants;
import com.ltedu.common.enums.ErrorCodeEnum;
import com.ltedu.common.exception.BaseException;
import com.ltedu.common.redis.RedisTool;
import com.ltedu.common.utils.MD5Utils;
import com.ltedu.common.utils.SecurityUtils;
import com.ltedu.common.vo.Result;
import com.ltedu.user.domain.Member;
import com.ltedu.user.domain.vo.LoginVO;
import com.ltedu.user.domain.vo.RegisterVO;
import com.ltedu.user.mapper.MemberMapper;
import com.ltedu.user.service.LoginLogService;
import com.ltedu.user.service.MemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ltedu.common.utils.JwtUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author Jerry
 * @since 2020-11-26
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

    @Autowired
    private RedisTool redisTool;

    @Autowired
    private LoginLogService loginLogService;

    /**
     * 用户注册
     *
     * @param registerVO
     * @return {@link Boolean}
     */
    @Override
    public Boolean register(RegisterVO registerVO) {
        if (!StringUtils.equals(registerVO.getPassword(), registerVO.getConfirmPassword())) {
            throw new BaseException(ErrorCodeEnum.TWO_INPUT_PASSWORD_NOT_MATCH);
        }
        String code = (String) redisTool.get(Constants.SEND_SMS_KEY + registerVO.getMobile());
        if (!StringUtils.equals(code, registerVO.getCode())) {
            throw new BaseException(ErrorCodeEnum.SMS_CODE_ERROR);
        }

        // 判断手机号是否已注册
        int count = this.baseMapper.selectCount(new LambdaQueryWrapper<Member>().
                eq(Member::getMobile, registerVO.getMobile()));
        if (count > 0) {
            throw new BaseException(ErrorCodeEnum.MOBILE_IS_REGISTERED);
        }

        Member member = new Member();
        member.setNickname(registerVO.getNickname());
        member.setPassword(SecurityUtils.encryptPassword(registerVO.getPassword()));
        member.setMobile(registerVO.getMobile());
        member.setDeleted(Constants.NOT_DELETED);
        member.setGmtCreate(new Date());
        member.setGmtModified(new Date());
        member.setState(Constants.NORMAL);
        member.setHeadImgUrl(Constants.DEFAULT_HEAD_IMG_URL);
        member.setUserType(1);
        int rows = this.baseMapper.insert(member);
        if (rows == 0) {
            throw new BaseException(ErrorCodeEnum.REGISTERED_FAIL);
        }
        return rows > 0;
    }

    /**
     * 用户登录
     *
     * @param loginVO
     * @param ip
     * @return {@link Result}
     */
    @Override
    public Result login(LoginVO loginVO, String ip) {
        Member member = this.baseMapper.selectOne(new LambdaQueryWrapper<Member>().
                eq(Member::getMobile, loginVO.getMobile()));
        if (member == null) {
            loginLogService.saveLoginLog(member.getId(), ip, Constants.FROZEN);
            throw new BaseException(ErrorCodeEnum.USER_NOT_FOUND);
        }
        String password = MD5Utils.md5(SecurityUtils.encryptPassword(loginVO.getPassword()));
        if (!StringUtils.equals(password, member.getPassword())) {
            loginLogService.saveLoginLog(member.getId(), ip, Constants.FROZEN);
            throw new BaseException(ErrorCodeEnum.PASSWORD_ERROR);
        }
        if(member.getState().equals(Constants.FROZEN)) {
            loginLogService.saveLoginLog(member.getId(), ip, Constants.FROZEN);
            throw new BaseException(ErrorCodeEnum.USER_DISABLED);
        }
        String jwtToken = JwtUtils.createJwtToken(member.getId(), member.getNickname());
        // 保存登录日志
        loginLogService.saveLoginLog(member.getId(), ip, Constants.NORMAL);
        return Result.ok(jwtToken);
    }

}
